package cc.rboot.permission.interceptor;

import cc.rboot._core.holder.AppContextHolder;
import cc.rboot.permission.annotation.RequireResourcePermission;
import cc.rboot.permission.core.IFullAccessResourcePermission;
import cc.rboot.permission.core.IReadOnlyResourcePermission;
import cc.rboot.permission.core.IResourcePermission;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Order
@Component
public class ResourcePermissionInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = ((HandlerMethod) handler);

        RequireResourcePermission permission = handlerMethod.getMethodAnnotation(RequireResourcePermission.class);
        if (permission == null) {
            permission = handlerMethod.getBeanType().getAnnotation(RequireResourcePermission.class);
        }
        if (permission == null) {
            return true;
        }

        IFullAccessResourcePermission fullAccessResourcePermission = AppContextHolder.get().getBeanProvider(IFullAccessResourcePermission.class).getIfAvailable();
        if (fullAccessResourcePermission !=null && fullAccessResourcePermission.has()) {
            return true;
        }

        IReadOnlyResourcePermission readOnlyResourcePermission = AppContextHolder.get().getBeanProvider(IReadOnlyResourcePermission.class).getIfAvailable();
        if (readOnlyResourcePermission !=null && readOnlyResourcePermission.has() && "GET".equals(request.getMethod())) {
            return true;
        }

        StringBuilder builder = new StringBuilder(" ");
        Class<? extends IResourcePermission>[] resourcePermissionClass = permission.value();
        for (Class<? extends IResourcePermission> permissionClass : resourcePermissionClass) {
            final IResourcePermission bean = AppContextHolder.getBean(permissionClass);
            if (bean.has()) {
                return true;
            }
            builder.append(bean.name()).append(" ");
        }
        throw new RuntimeException("资源权限不足，此处需要【" + builder + "】的资源权限");
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    }
}
